/**
 * 
 */
package org.vsg.security.authorization;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import org.jsecurity.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vsg.platform.view.vo.Menu;
import org.vsg.platform.view.vo.MenuItem;
import org.vsg.platform.view.vo.Url;
import org.vsg.security.model.domain.SysMenuResource;
import org.vsg.security.model.domain.SysResource;
import org.vsg.security.model.domain.UrlResource;
import org.vsg.security.model.persistence.ResourceAssociationDao;
import org.vsg.security.model.persistence.SysMenuResourceDao;
import org.vsg.security.model.persistence.SysRoleDao;
import org.vsg.security.model.persistence.UrlResourceDao;

/**
 * @author Bill Vison
 *
 */
public class BasicMenuAuthorization implements MenuAuthorization {

	private static final Logger logger = LoggerFactory.getLogger(BasicMenuAuthorization.class);
	
	private SysRoleDao sysRoleDao;
	
	private ResourceAssociationDao resourceAssociationDao;	
	
	private SysMenuResourceDao sysMenuResourceDao;
	
	private UrlResourceDao urlResourceDao;

	
	public SysRoleDao getSysRoleDao() {
		return sysRoleDao;
	}


	public void setSysRoleDao(SysRoleDao sysRoleDao) {
		this.sysRoleDao = sysRoleDao;
	}

	public UrlResourceDao getUrlResourceDao() {
		return urlResourceDao;
	}


	public void setUrlResourceDao(UrlResourceDao urlResourceDao) {
		this.urlResourceDao = urlResourceDao;
	}


	public ResourceAssociationDao getResourceAssociationDao() {
		return resourceAssociationDao;
	}


	public void setResourceAssociationDao(
			ResourceAssociationDao resourceAssociationDao) {
		this.resourceAssociationDao = resourceAssociationDao;
	}


	public SysMenuResourceDao getSysMenuResourceDao() {
		return sysMenuResourceDao;
	}


	public void setSysMenuResourceDao(SysMenuResourceDao sysMenuResourceDao) {
		this.sysMenuResourceDao = sysMenuResourceDao;
	}


	/* (non-Javadoc)
	 * @see org.vsg.security.authorization.MenuAuthorization#authorization(org.jsecurity.subject.Subject)
	 */
	@Override
	public Menu authorization(Subject currentUser) {
		// TODO Auto-generated method stub
		Menu menu = new Menu();
		menu.setId(currentUser.toString());
		// --- find the rooe menus ---
		Set<SysMenuResource> menus = this.sysMenuResourceDao.findAvailableRoot();		
		
		menu.setItem( generateTreeByMenuReource(menus ,  currentUser) );
		
		return menu;
	}
	
	private List<MenuItem> generateTreeByMenuReource(Set<SysMenuResource> menus , Subject authUser) {
		List<MenuItem> items = new Vector<MenuItem>();
		SysMenuResource resource = null;
		MenuItem item = null;
		org.vsg.security.authz.permission.menu.ACCESS perm = null;
		for (Iterator<SysMenuResource> menuIter = menus.iterator() ; menuIter.hasNext() ; ) {
			// --- generate resource ---
			resource = menuIter.next();
			perm = new org.vsg.security.authz.permission.menu.ACCESS();
			perm.setResource( resource );
			
			// --- auth permission ---
			if (authUser.isPermitted( perm ) ) {
				// --- build the item defined ---
				item = new MenuItem();
				item.setId( resource.getCode() );
				item.setName( resource.getName() );
				
				Collection<SysMenuResource> subChildren = this.sysMenuResourceDao.findChildrenResource( resource );
				
				if ( subChildren.isEmpty() ) {
					if (resource.getFlagStrategy() == 1) {
						Url url = new Url();
						SysResource assoRes = resource.getAssociationResource();
						UrlResource urlRes = urlResourceDao.load( assoRes.getId() );
						
						// --- set the relative url ---
						String urlStr = "../" + urlRes.getContext() +"/" + urlRes.getUrl();
						
						url.setValue( urlStr );
						
						// --- set the item ---
						item.setUrl( url );					
					}

				} else {
					item.setItem( generateTreeByMenuReource(new HashSet(subChildren) , authUser) );
				}
				
				items.add( item );
			}
			
		
		}
		return items;
	}

}
